<!--
 * @Author: 四川华西绿舍建材有限公司
 * @Date: 2023-11-28 16:21:53
 * @LastEditors: 陈波
 * @LastEditTime: 2024-04-26 21:02:31
 * @Description: 
 * @FilePath: \graDesign\src\views\SystemManagement\UserManagement\index.vue
-->
<template>
  <div>
    <LayoutIndex> 
      <span>欢迎您，{{ identity }} -- </span>
      <span class="user-name">{{ userInfo.username }}</span>
    </LayoutIndex>
    <LayoutDetail>
      <div class="mainF">
        <div class="treeF">
          <el-tree
            class="tree-line"
            :data="data"
            :props="defaultProps"
            :icon="CaretRight"
            @node-click="handleNodeClick"
          />
        </div>
        <div class="tableF" style="position: relative; overflow: hidden">
          <div class="operations">
            <div class="btns">
              <el-button 
                type="primary" 
                plain 
                :icon="Check"
                @click="changeStatus('enable')"
              >启用</el-button>
              <el-button 
                type="warning" 
                plain 
                :icon="Remove"
                @click="changeStatus('disable')"
              >禁用</el-button>
              <el-button 
                type="success" 
                plain
                @click="resetPasswordFn"
              >重置密码</el-button>
              <el-button 
                type="danger" 
                :icon="CloseBold"
                @click="bulkDeleteFn"
              >批量删除</el-button>
              <el-button
                type="danger"
                plain
                :icon="Upload"
                @click="exportExcelFn"
              >导出</el-button>
            </div>
            <div class="tools">
              <div
                class="tool_item"
                :style="{ fontSize: fontSize }"
                @click="enterOrExitFullScreen('EnterFullScreen')"
              >
                <BasicIcon iconName="icon-fullscreen-expand" class="tool_icon" />
              </div>
              <div class="tool_item" :style="{ fontSize: fontSize }">
                <BasicIcon iconName="icon-filter" class="tool_icon" />
                <el-dropdown trigger="click" :hide-on-click="false">
                  <span class="el-dropdown-link tool_item"> 筛选 </span>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item
                        v-for="(item, index) in tableColumns"
                        :key="index"
                      >
                        <el-checkbox v-model="item.status">{{
                          item.label
                        }}</el-checkbox>
                      </el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
              <div
                class="tool_item"
                :style="{ fontSize: fontSize }"
                @click="clickSearch"
              >
                <BasicIcon iconName="icon-search" class="tool_icon" />
                <span>高级搜索</span>
              </div>
            </div>
          </div>
          <BasicTable
            :loading="tableFreshFlag"
            :tableData="tableData"
            :tableColumns="tableColumns"
            :isIndex="false"
            :option="option"
            @selectionChange="handleSelectionChange"
            @handleCurrentChange="handleCurrentChange"
            @handleSizeChange="handleSizeChange"
            @postDomRef="receiveTableDom"
            @refreshTable="refreshTable"
            :fit="true"
            :border="true"
          >
            <template #avatar="{ row }">
              <el-image
                style="width: 100px; height: 100px; cursor: pointer"
                :src="row.avatar"
                fit="contain"
                @click="showImg(row.avatar)"
              />
            </template>
            <template #faceBase="{ row }">
              <el-image
                style="width: 100px; height: 100px; cursor: pointer"
                :src="row.faceBase"
                fit="contain"
                @click="showImg(row.faceBase)"
              />
            </template>
            <template #ismanager="{ row }">
              <el-tag v-if="row.ismanager == 2">超级管理员</el-tag>
              <el-tag v-else-if="row.ismanager == 1">管理员</el-tag>
              <el-tag v-else type="success">用户</el-tag>
            </template>
            <template #status="{ row }">
              <el-tag v-if="row.status" type="success">启用</el-tag>
              <el-tag v-else type="danger">禁用</el-tag>
            </template>
            <template #operation="{ row }">
              <BasicTooltip content="详情描述" position="top">
                <el-button 
                  type="primary" 
                  :icon="Star"
                  @click="openUserDialog('detail', row)"
                >详情</el-button>
              </BasicTooltip>
              <el-button
                type="success"
                :icon="Edit"
                @click="openUserDialog('update', row)"
                >编辑</el-button
              >
              <!-- v-if="!isNowUserAccount(row)" -->
              <el-button
                type="danger"
                :icon="Delete"
                @click="deleteUserByUserId(row)"
                >删除</el-button
              >
            </template>
          </BasicTable>
          <BasicDrawer
            :drawer="drawer"
            :formData="searchFormData"
            direction="rtl"
            size="35%"
            @handleClose="handleClose"
            @resetForm="reset"
            @onSubmit="onSubmit"
          />
        </div>
      </div>
    </LayoutDetail>
    <!-- 查看头像/人脸 -->
    <BasicDialog
      :visible="imgDialogVisible"
      width="30%"
      :showClose="true"
      @handleClose="closeShowImgDialog"
    >
      <img
        style="width: 100%; height: 100%"
        :src="imgShowURL"
        alt="暂无图片..."
      />
    </BasicDialog>
    <!-- 查看/编辑用户信息 -->
    <detailAndUpdate 
      v-if="userDialogVisible"
      :userDialogVisible="userDialogVisible"
      :title="userDialogTitle"
      :data="dataRow"
      :type="userDialogType"
      @handleClose="closeUserDialog"
    />
  </div>
</template>

<script setup lang="ts">
import {
  CaretRight,
  Check,
  CloseBold,
  Remove,
  Delete,
  Edit,
  Star,
  Upload,
} from "@element-plus/icons-vue";
import { ElMessageBox } from 'element-plus'
import { ref, onMounted, computed, inject } from "vue";
import useLoginStore from "@/store/login";
import { storeToRefs } from "pinia";
// 测试导出
import { exportToExcel, exportExcelByAuto } from "@/utils/exportToExcel.js";
import { tableColumns } from "./headerTitle";
// api
import userApi from "@/request/api/user";
// 主题
import useThemeConfigStore from "@/store/themeConfig";
// component
import detailAndUpdate from "./detailAndUpdate.vue";
import { showMessageBox } from "@/utils/alertMsg";

const themeConfigStore = useThemeConfigStore();
const { getThemeFontSize: fontSize } = storeToRefs(themeConfigStore);
const loginStore = useLoginStore();
const { userInfo } = storeToRefs(loginStore);

const enterOrExitFullScreen: Function = inject("enterOrExitFullScreen");

const identity = computed(() => {
  let str: string = '';
  if(userInfo.value.ismanager == 0) {
    str = '用户';
  } else if (userInfo.value.ismanager == 1) {
    str = '管理员';
  } else if (userInfo.value.ismanager == 2) {
    str = '超级管理员';
  }
  return str;
})

interface Tree {
  label: string;
  children?: Tree[];
}

let indicator = ref<number>(2);

const handleNodeClick = (data: Tree) => {
  if (data.label == "组织树") {
    return;
  }
  if (data.label == "普通用户") {
    indicator.value = 0;
  }
  if (data.label == "管理人员") {
    indicator.value = 1;
  }
  if (data.label == "全部") {
    indicator.value = 2;
  }
  getTableData(indicator.value);
};

const data: Tree[] = [
  {
    label: "组织树",
    children: [
      {
        label: "全部",
      },
      {
        label: "普通用户",
      },
      {
        label: "管理人员",
      },
    ],
  },
];

const defaultProps = {
  children: "children",
  label: "label",
};

// 用户头像和人脸大小size
let imgShowURL = ref<string>("");
let imgDialogVisible = ref<boolean>(false);

const showImg = (url: string) => {
  imgShowURL.value = url;
  imgDialogVisible.value = true;
};
const closeShowImgDialog = () => {
  imgDialogVisible.value = false;
};

/** 表格 **/
let option = ref({
  page: 1,
  pageSize: 5,
  total: 0,
  pageSizes: [1, 5, 10, 20, 30, 40, 50],
});

// 静态死数据
let tableData = ref<Array<any>>([]);

// type 0: 获取所有权限为用户的 1: 获取所有权限管理员 2：所有数据
const getTableData = (type: number) => {
  const params = {
    page: option.value.page,
    pageSize: option.value.pageSize,
    type,
  };
  tableFreshFlag.value = true;
  userApi
    .getUsersList(params)
    .then((res: any) => {
      if (res.code == 200) {
        tableData.value = res.data.userList;
        option.value.total = res.data.total;
      } else {
        showMessageBox("error", res.msg);
      }
    })
    .finally(() => {
      tableFreshFlag.value = false;
    });
};
onMounted(() => {
  getTableData(indicator.value);
});

let tableDom = ref<any>(null);
// 选中的数组
let selectRows = ref<any[]>([]);
// 选择回调
const handleSelectionChange = (val: any) => {
  selectRows.value = val;
};
// 分页
const handleCurrentChange = (val: number) => {
  option.value.page = val;
  getTableData(indicator.value);
};
// 改变每页显示条数
const handleSizeChange = (val: number) => {
  option.value.pageSize = val;
  getTableData(indicator.value);
};
// 获取
const receiveTableDom = (dom: HTMLElement) => {
  tableDom.value = dom;
};
let tableFreshFlag = ref<boolean>(false);
// 刷新表格
const refreshTable = () => {
  getTableData(indicator.value);
};

const exportExcelFn = () => {
  // 方法一：传递dom，默认全部导出
  exportToExcel("users.xlsx", tableDom.value.$el);
  // 方法二：传递数据导出，需要自定义表头文案
  // const titleArr = [
  //   "用户ID",
  //   "用户名",
  //   "联系方式",
  //   "创建时间"
  // ]; //表头中文名
  // exportExcelByAuto(tableData, "用户表", titleArr, "sheetName");
};

const isEmpty = computed(() => {
  return selectRows.value.length == 0
})
// 封装批量常用函数
/**
 * @param msg 提示消息
 * @param url 请求方法（参数）
 * @param type 启禁用
 */
const bulkCommonFn = (msg: string, url: Function, type?: number) => {
  if(isEmpty.value) {
    showMessageBox('warning', '请选择要操作的用户')
    return
  }
  ElMessageBox.confirm(
    msg,
    'Warning',
    {
      confirmButtonText: '继续',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
  .then(() => {
    tableFreshFlag.value = true;
    let params = {
      type,
      userIdArray: selectRows.value.map((item: any) => item.userid)
    }
    url(params).then((res: any) => {
      if(res.code == 200) {
        showMessageBox('success', res.msg)
        getTableData(indicator.value);
        selectRows.value = [];
      } else{
        showMessageBox('error', res.msg)
      }
    }).finally(() => {
      tableFreshFlag.value = false;
    })
  })
  .catch(() => {
    showMessageBox('info', '取消操作', 3000, false);
  })
}

// 批量修改状态
const changeStatus = (type: 'enable' | 'disable') => {
  const str = type == 'enable' ? '启用' : '禁用';
  const mark = type == 'enable' ? 1 : 0;
  bulkCommonFn(`是否批量${str}账号?`, userApi.enableOrDisableUserBulk, mark)
};

// 批量重置密码：默认123456@abc
const resetPasswordFn = () => {
  bulkCommonFn('是否重置密码为123456@abc，是否继续？', userApi.resetPasswordBulk);
};

// 批量删除
const bulkDeleteFn = () => {
  bulkCommonFn('此删除操作不可逆，是否继续？', userApi.deleteUserBulk);
}

let userDialogVisible = ref<boolean>(false);
let userDialogTitle = ref<string>('')
let dataRow = ref<any>({});
let userDialogType = ref<'' |'detail' | 'update'>('');
// 打开用户编辑弹窗
const openUserDialog = (type: 'detail' | 'update', row: any) => {
  dataRow.value = row;
  userDialogVisible.value = true;
  if(type == 'detail') {
    userDialogTitle.value = '详情'
    userDialogType.value = 'detail';
  }
  if(type == 'update') {
    userDialogTitle.value = '编辑用户信息'
    userDialogType.value = 'update';
  }
}
const closeUserDialog = () => {
  userDialogVisible.value = false;
}

// 单个删除用户
const deleteUserByUserId = (row: any) => {
  ElMessageBox.confirm(
    '此删除操作不可逆，是否继续？',
    'Warning',
    {
      confirmButtonText: '继续',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
  .then(() => {
    userApi.deleteUserByUserId({
      userid: row.userid
    }).then((res: any) => {
      if(res.code == 200) {
        showMessageBox('success', res.msg, 3000, false);
        getTableData(indicator.value);
      } else{
        showMessageBox('error', res.msg, 3000, false);
      }
    })
  })
  .catch(() => {
    showMessageBox('info', '取消操作', 3000, false);
  })
}
/** 表格结束 **/

const isNowUserAccount = computed(() => {
  return (row: any) => {
    return userInfo.value.userid == row.userid;
  };
});

/** 高级搜索 **/
let drawer = ref<boolean>(false);
let searchFormData = {
  rules: {},
  labelWidth: "80px",
  inline: false,
  labelPosition: "left",
  size: "default",
  formItem: [
    {
      type: "text",
      label: "用户名:",
      isDisabled: false,
      placeholder: "请输入",
      prop: "username",
      value: "",
      required: true,
    },
    {
      type: "select",
      isDisabled: false,
      // 是否开启多选
      multiple: false,
      label: "权限:",
      prop: "auth",
      value: [],
      selectLabel: "label",
      selectvalue: "value",
      options: [
        { selectkey: "manager", label: "管理员", value: 1 },
        { selectkey: "user", label: "用户", value: 0 },
      ],
    },
    {
      type: "datetimerange",
      label: "创建时间:",
      isDisabled: false,
      placeholder: "请输入",
      prop: "createTime",
      value: "",
      required: true,
    },
    {
      type: "select",
      isDisabled: false,
      // 是否开启多选
      multiple: false,
      label: "状态:",
      prop: "status",
      value: [],
      selectLabel: "label",
      selectvalue: "value",
      options: [
        { selectkey: "open", label: "启用", value: 1 },
        { selectkey: "close", label: "禁用", value: 0 },
      ],
    },
  ],
};

const clickSearch = () => {
  drawer.value = true;
};
const handleClose = () => {
  drawer.value = false;
};
const reset = () => {
  drawer.value = false;
  getTableData(indicator.value);
};
const onSubmit = (val: any) => {
  let params = {
    username: val.username || "",
    auth: val.auth,
    status: val.status,
    startTime: "",
    endTime: "",
    page: option.value.page,
    pageSize: option.value.pageSize,
  };
  if (val.createTime && val.createTime.length > 0) {
    params.startTime = val.createTime[0];
    params.endTime = val.createTime[1];
  }
  tableFreshFlag.value = true;
  userApi.getUsersListBySearch(params).then((res: any) => {
    if (res.code == 200) {
      tableData.value = res.data.userList;
      option.value.total = res.data.total;
    }
  }).finally(() => {
    tableFreshFlag.value = false;
  });
  handleClose();
};
</script>

<style scoped lang="scss">
.user-name {
  color: $aside-active-color;
}

.mainF {
  display: flex;
  .treeF {
    width: 15%;
    border: 1px solid #efefef;
    overflow-x: scroll;
  }
  .tableF {
    width: 85%;
    height: 100%;
    padding: 0px 10px 10px 10px;
    .operations {
      margin-bottom: 10px;
      display: flex;
      justify-content: space-between;

      .tools {
        display: flex;
        gap: 20px;
        .tool_item {
          display: flex;
          align-items: center;
          gap: 8px;
          &:hover {
            cursor: pointer;
            color: $aside-active-color;
          }
        }
      }
    }
  }
}
</style>
